﻿using MediatR;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Practice.Common.DbCont;
using Practice.Common.Infrastructure.Interfaces;
using Practice.Common.Infrastructure.Repositories;
using System.Reflection;
using System.Text;
using NLog.Web;

namespace Practice.API.Common
{
    public static class ExtensionServiceCollection
    {
        public static void AddService(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddDbContext<EFDbContext>(x =>
            {
                x.UseSqlServer(configuration.GetConnectionString("DB"));
            });
            services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));
            services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(x =>
            {
                var path = AppDomain.CurrentDomain.BaseDirectory + "Practice.API.xml";
                x.IncludeXmlComments(path, true);
            });
            
            //注册中介者
            services.AddMediatR(Assembly.GetExecutingAssembly());
            //AutoMapper
            services.AddAutoMapper(typeof(AutoMapperProfile));
            //读取配置文件的jwt的配置
            var jwtSettings = configuration.GetSection("JWT").Get<JwtSettings>();
            //添加认证
            //// 设置默认的身份验证为 JwtBearer
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            // 配置 JWT Bearer 选项
            .AddJwtBearer(options =>
            {
                // 配置 Token 验证参数
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //过期时间容错值，解决服务器端时间不同步问题（秒）
                    //允许服务器时间偏移量30秒，即我们配置的过期时间加上这个允许偏移的时间值，才是真正过期的时间(过期时间 + 偏移值)你也可以设置为0，ClockSkew = TimeSpan.Zero
                    ClockSkew = TimeSpan.FromSeconds(30),
                    ValidateIssuer = true,// 验证发行者
                    ValidateAudience = true, // 验证受众
                    ValidateLifetime = true, // 验证令牌有效期
                    ValidateIssuerSigningKey = true,// 验证签名密钥
                    ValidIssuer = jwtSettings.Issuer,// 发行者
                    ValidAudience = jwtSettings.Audience,// 受众
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecurityKey))// 签名密钥
                };
            });
            
            // 配置Swagger
            services.AddSwaggerGen(o =>
            {
                // 显示 授权信息
                o.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
                {
                    Description = "添加JWT授权Token：Bearer Token值",
                    Name = "Authorization",
                    In = Microsoft.OpenApi.Models.ParameterLocation.Header,
                    Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                o.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[]
                        {

                        }
                    }
                });
            });
            

        }
        public static void AddDBContext(this IServiceCollection services, IConfiguration configuration)
        {
            //EF上下文
            services.AddDbContext<EFDbContext>(p =>
            {
                p.UseSqlServer(configuration.GetConnectionString("DB"));
            });
        }
        public static void AddIdentityService(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddHttpContextAccessor();
            services.AddScoped<IIdentityService, IdentityService>();
        }
    }
}
